package common

import (
	"crypto/md5"
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"reflect"
	"sort"
	"strings"
)

func getSignContent(data map[string]interface{}) string {
	b := make([]string, 0)
	sorted_keys := make([]string, 0)

	for key, _ := range data {
		if data[key] == nil {
			continue
		}
		if key == "sign" {
			continue
		}
		sorted_keys = append(sorted_keys, key)
	}

	// sort 'string' key in increasing order
	sort.Strings(sorted_keys)

	for _, key := range sorted_keys {
		b = append(b, key+"="+fmt.Sprintf("%v", data[key]))
	}
	return strings.Join(b, "&")
}

func SignSha1(data interface{}) string {
	dm, ok := data.(map[string]interface{})
	if !ok {
		dm = interface2map(data)
	}
	content := getSignContent(dm)
	r := sha1.Sum([]byte(content))
	return hex.EncodeToString(r[:])
}

func interface2map(data interface{}) map[string]interface{} {
	result := make(map[string]interface{})
	objT := reflect.TypeOf(data)
	objV := reflect.ValueOf(data)
	for i := 0; i < objT.NumField(); i++ {
		result[objT.Field(i).Name] = objV.Field(i).Interface()
	}
	return result
}

func Md5(str string) string {
	r := md5.Sum([]byte(str))
	return hex.EncodeToString(r[:])
}
